﻿using System.Linq;
using Abp;
using Abp.Authorization;
using Abp.Authorization.Roles;
using Abp.Authorization.Users;
using Abp.MultiTenancy;
using Abp.Notifications;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using ARchGL.Platform.Authorization;
using ARchGL.Platform.Authorization.Roles;
using ARchGL.Platform.Authorization.Users;
using ARchGL.Platform.EntityFrameworkCore;
using ARchGL.Platform.Notifications;
using Abp.Extensions;
using ARchGL.Platform.Core;
using ARchGL.Platform.Authorization.Permissions;
using System.Collections.Generic;

namespace ARchGL.Platform.Migrations.Seed.Tenants
{
    public class TenantRoleAndUserBuilder
    {
        private readonly TenantDbContext _context;
        private readonly int _tenantId;
        private IGuidGenerator GuidGenerator { get; set; }

        public TenantRoleAndUserBuilder(TenantDbContext context, int tenantId)
        {
            _context = context;
            _tenantId = tenantId;
            GuidGenerator = SequentialGuidGenerator.Instance;
        }

        public void Create()
        {
            CreateRolesAndUsers();
        }

        private void CreateRolesAndUsers()
        {
            //Admin role （系统管理员）
            var adminRole = GetRolesByName(StaticRoleNames.Tenants.Admin);
            if (adminRole == null)
            {
                adminRole = _context.Roles.Add(GetRole(StaticRoleNames.Tenants.Admin, "系统管理员")).Entity;
                _context.SaveChanges();
            }

            //Project role（项目管理员）
            if (GetRolesByName(StaticRoleNames.Tenants.Project) == null)
            {
                _context.Roles.Add(GetRole(StaticRoleNames.Tenants.Project, "项目管理员"));
                _context.SaveChanges();
            }

            ////BranchCompany role （子公司管理员）
            //if (GetByName(StaticRoleNames.Tenants.BranchCompany) == null)
            //{
            //    _context.Roles.Add(GetRole(StaticRoleNames.Tenants.BranchCompany, "子公司管理员"));
            //    _context.SaveChanges();
            //}

            //Normal role（普通用户）
            if (GetRolesByName(StaticRoleNames.Tenants.Normal) == null)
            {
                _context.Roles.Add(GetRole(StaticRoleNames.Tenants.Normal, "普通用户", true));
                _context.SaveChanges();
            }

            ////Special role（特定用户）
            //if (GetByName(StaticRoleNames.Tenants.Special) == null)
            //{
            //    _context.Roles.Add(GetRole(StaticRoleNames.Tenants.Special, "特定用户", true));
            //    _context.SaveChanges();
            //}

            //InterfaceRole1（开放接口角色1）
            var interfaceRole1 = GetRolesByName(StaticRoleNames.Tenants.InterfaceRole1);
            if (interfaceRole1 == null)
            {
                interfaceRole1 = _context.Roles.Add(GetRole(StaticRoleNames.Tenants.InterfaceRole1, "开放接口角色", true)).Entity;
                _context.SaveChanges();
            }

            //admin user
            {
                var adminUser = _context.Users.IgnoreQueryFilters().FirstOrDefault(u => u.TenantId == _tenantId && u.UserName == AbpUserBase.AdminUserName);
                if (adminUser == null)
                {
                    adminUser = User.CreateTenantAdminUser(_tenantId, "admin@tennat.com");
                    adminUser.PrimaryId = StaticUserIds.Tenants.Admin;
                    adminUser.Password = new PasswordHasher<User>(new OptionsWrapper<PasswordHasherOptions>(new PasswordHasherOptions())).HashPassword(adminUser, "123qwe".ToMd5());
                    adminUser.Type = UserType.租户管理员;
                    adminUser.IsEmailConfirmed = true;
                    adminUser.ShouldChangePasswordOnNextLogin = false;
                    adminUser.IsActive = true;

                    _context.Users.Add(adminUser);
                    _context.SaveChanges();

                    //Assign Admin role to admin user
                    _context.UserRoles.Add(new UserRole(_tenantId, adminUser.Id, adminRole.Id));
                    _context.SaveChanges();

                    ////User account of admin user
                    //if (_tenantId == 1)
                    //{
                    //    _context.UserAccounts.Add(new UserAccount
                    //    {
                    //        TenantId = _tenantId,
                    //        UserId = adminUser.Id,
                    //        UserName = AbpUserBase.AdminUserName,
                    //        EmailAddress = adminUser.EmailAddress
                    //    });
                    //    _context.SaveChanges();
                    //}

                    //Notification subscription
                    _context.NotificationSubscriptions.Add(new NotificationSubscriptionInfo(SequentialGuidGenerator.Instance.Create(), _tenantId, adminUser.Id, AppNotificationNames.NewUserRegistered));
                    _context.SaveChanges();
                }
            }
            {//接口对接用户
                var user = _context.Users.IgnoreQueryFilters().FirstOrDefault(u => u.TenantId == _tenantId && u.PrimaryId == StaticUserIds.Tenants.UserInterface);
                if (user == null)
                {
                    //帐号：1ecee2c4-3312-4e5c-ad70-cb641fbd35e9
                    //密码：f06cd96a-9a1e-497f-a2ac-64596a6e3805
                    user = User.CreateTenantNormalUser(_tenantId, "1ecee2c4-3312-4e5c-ad70-cb641fbd35e9", "接口专用", "1ecee2c4-3312-4e5c-ad70-cb641fbd35e9@am.com");
                    user.PrimaryId = StaticUserIds.Tenants.UserInterface;
                    user.Password = new PasswordHasher<User>(new OptionsWrapper<PasswordHasherOptions>(new PasswordHasherOptions())).HashPassword(user, "f06cd96a-9a1e-497f-a2ac-64596a6e3805".ToMd5());
                    user.Type = UserType.接口租户;
                    user.IsEmailConfirmed = false;
                    user.ShouldChangePasswordOnNextLogin = false;
                    user.IsActive = true;

                    _context.Users.Add(user);
                    _context.SaveChanges();

                    //Assign InterfaceRole role to admin user
                    _context.UserRoleExtend.Add(new UserRoleExtend(_tenantId, user.Id, user.PrimaryId, interfaceRole1.Id));
                    _context.SaveChanges();

                    ////PermissionManager
                    //var grantedPermissionNames = new List<string> {
                    //    AppPermissions.AMJ, AppPermissions.AMJ_Jianwei
                    //};
                    //var grantedPermissions = PermissionManager.GetPermissionsFromNamesByValidating(grantedPermissionNames);
                    //_context.Permissions.AddRange(grantedPermissions);
                }
            }
        }

        private Role GetRolesByName(string name)
        {
            return _context.Roles.IgnoreQueryFilters().FirstOrDefault(r => r.TenantId == _tenantId && r.Name == name);
        }

        private Role GetRole(string name, string displayName, bool isDefault = false)
        {
            return new Role(_tenantId, name, displayName)
            {
                IsStatic = true,
                IsDefault = isDefault,
                Description = displayName,
            };
        }
    }
}
